package com.tanhua.dubbo.server.api;

import com.alibaba.dubbo.config.annotation.Service;
import com.mongodb.client.result.DeleteResult;
import com.tanhua.dubbo.server.pojo.*;
import com.tanhua.dubbo.server.service.IdService;
import com.tanhua.dubbo.server.vo.PageInfo;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 实现圈子功能
 */
@Service(version = "1.0.0")
public class QuanZiApiImpl implements QuanZiApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;


    /**
     * 保存发布者信息
     *
     * @param publish
     * @return
     */
    @Override
    public String savePublish(Publish publish) {

        // 1.校验传入的发布信息的对象是否为空,若为空则返回false
        if (publish.getUserId() == null) {
            return null;
        }

        try {
            //2.设置发布的创建时间以及主键id
            publish.setCreated(System.currentTimeMillis()); //设置创建时间
            publish.setId(ObjectId.get()); //设置id
            publish.setSeeType(1);  //查看权限

            /**
             * 增加自增长pid
             */
            publish.setPid(this.idService.createId("publish",publish.getId().toHexString()));

            //2.1调用mongoTemplate保存信息
            this.mongoTemplate.save(publish); //保存发布


            //3.构造相册对象
            Album album = new Album(); // 构建相册对象

            //3.1设置发布时间,创建时间和主键id
            album.setPublishId(publish.getId());
            album.setCreated(System.currentTimeMillis());
            album.setId(ObjectId.get());

            //3.2调用mongoTemplate保存相册信息,并且设置表名,因为是保存在自己的相册中,所有获取的是自己的id值
            this.mongoTemplate.save(album, "quanzi_album_" + publish.getUserId());

            //4.写入好友的时间线中
            //4.1设置查询条件,查询Tanhua_users表中userId与发布者id相同的用户(用来找到他的所有朋友)
            Criteria criteria = Criteria.where("userId").is(publish.getUserId());

            //4.2通过mongoTemplate查找,返回的是Users集合对象
            List<Users> users = this.mongoTemplate.find(Query.query(criteria), Users.class);

            //4.3遍历集合对象,设置时间线中的值
            for (Users user : users) {
                TimeLine timeLine = new TimeLine();
                timeLine.setId(ObjectId.get());
                timeLine.setPublishId(publish.getId());
                timeLine.setUserId(user.getUserId());
                timeLine.setDate(System.currentTimeMillis());

                //4.4通过mongoTemplate进行保存,表名是朋友的id,因为是把发布信息保存到朋友的时间线表中
                this.mongoTemplate.save(timeLine, "quanzi_time_line_" + user.getFriendId());
            }

            return publish.getId().toHexString();
        } catch (Exception e) {
            e.printStackTrace();
            //TODO 出错的事务回滚
        }

        return null;
    }

    /**
     * 查询发布者列表
     * @param userId
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<Publish> queryPublishList(Long userId, Integer page, Integer pageSize) {
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("date")));
        Query query = new Query().with(pageRequest);

        //若未传入用户id,则表示查询推荐时间线表
        String collectionName = "quanzi_time_line_" + userId;
        if (userId == null) {
            collectionName = "quanzi_time_line_recommend";
        }

        //查询时间线表
        List<TimeLine> timeLineList = this.mongoTemplate.find(query, TimeLine.class, collectionName);

        //通过查询到的时间线表,获取发布者的id
        List<ObjectId> publishIds = new ArrayList<>();
        for (TimeLine timeLine : timeLineList) {
            publishIds.add(timeLine.getPublishId());
        }

        //查询发布信息
        Query queryPublish = Query.query(Criteria.where("id").in(publishIds)).with(Sort.by(Sort.Order.desc("created")));

        List<Publish> publishList = this.mongoTemplate.find(queryPublish, Publish.class);

        PageInfo<Publish> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal(0);
        pageInfo.setRecords(publishList);

        return pageInfo;
    }

    /**
     * 点赞
     *
     * @param userId
     * @param publishId
     * @return
     */
    @Override
    public boolean saveLikeComment(Long userId, String publishId) {
        Query query = new Query(Criteria.where("publishId").is(new ObjectId(publishId))
                .and("userId").is(userId)
                .and("commentType").is(1));

        long count = this.mongoTemplate.count(query, Comment.class);

        //如果已点赞,返回false
        if (count > 0) {
            return false;
        }

        return this.saveComment(userId, publishId, 1, null);
    }

    /**
     * 取消喜欢,点赞
     *
     * @param userId
     * @param publishId
     * @param commentType
     * @return
     */
    @Override
    public boolean removeComment(Long userId, String publishId, Integer commentType) {
        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(publishId))
                .and("userId").is(userId).and("commentType").is(commentType));

        DeleteResult remove = this.mongoTemplate.remove(query, Comment.class);
        return remove.getDeletedCount() > 0;
    }

    /**
     * 喜欢
     *
     * @param userId
     * @param publishId
     * @return
     */
    @Override
    public boolean saveLoveComment(Long userId, String publishId) {
        //编辑查询条件
        Query query = new Query(Criteria.where("publishId").is(new ObjectId(publishId))
                .and("userId").is(userId).and("commentType").is(3));

        long count = this.mongoTemplate.count(query, Comment.class);

        if (count > 0) {
            return false;
        }

        return this.saveComment(userId, publishId, 3, null);
    }

    /**
     * 发布评论
     *
     * @param userId
     * @param publishId
     * @param type
     * @param content
     * @return
     */
    @Override
    public boolean saveComment(Long userId, String publishId, Integer type, String content) {

        try {
            Comment comment = new Comment();
            comment.setContent(content);
            comment.setIsParent(true);
            comment.setCommentType(type);
            comment.setPublishId(new ObjectId(publishId));
            comment.setUserId(userId);
            comment.setId(ObjectId.get());
            comment.setCreated(System.currentTimeMillis());

            // 设置发布人的id
            Publish publish = this.mongoTemplate.findById(comment.getPublishId(), Publish.class);
            if (null != publish) {
                comment.setPublishUserId(publish.getUserId());
            } else {
                Video video = this.mongoTemplate.findById(comment.getPublishId(), Video.class);
                if (null != video) {
                    comment.setPublishUserId(video.getUserId());
                }
            }

            this.mongoTemplate.save(comment);

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }
    /**
     * 查询评论总条数
     *
     * @param publishId
     * @param type
     * @return
     */
    @Override
    public Long queryCommentCount(String publishId, Integer type) {
        Query query = new Query(Criteria.where("publishId").is(publishId).and("commentType").is(type));

        return this.mongoTemplate.count(query, Comment.class);
    }

    /**
     * 查询单条动态
     *
     * @param id
     * @return
     */
    @Override
    public Publish queryPublishById(String id) {
        return this.mongoTemplate.findById(new ObjectId(id), Publish.class);
    }


    /**
     * 动态信息评论
     * @param publishId
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<Comment> queryCommentList(String publishId, Integer page, Integer pageSize) {

        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.asc("created")));

        //根据发布者id和评论类型来删选
        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(publishId))
                .and("commentType").is(2)).with(pageRequest);

        //获取发布人,评论人和评论内容
        List<Comment> commentList = this.mongoTemplate.find(query, Comment.class);

        PageInfo<Comment> pageInfo = new PageInfo<>();
        pageInfo.setTotal(0);
        pageInfo.setPageSize(pageSize);
        pageInfo.setPageNum(page);
        pageInfo.setRecords(commentList);

        return pageInfo;

    }


    /**
     * 查询评论列表
     * @param userId
     * @param type
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<Comment> queryCommentListByUser(Long userId, Integer type, Integer page, Integer pageSize) {

        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("created")));
        Query query = new Query(Criteria
                .where("publishUserId").is(userId)
                .and("commentType").is(type)).with(pageRequest);

        List<Comment> commentList = this.mongoTemplate.find(query, Comment.class);

        PageInfo<Comment> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setRecords(commentList);
        pageInfo.setTotal(0); //不提供总数
        return pageInfo;
    }

    @Override
    public List<Publish> queryPublishByPids(List<Long> pids) {
        Query query = Query.query(Criteria.where("pid").in(pids));
        return this.mongoTemplate.find(query,Publish.class);
    }

    /**
     * 查询相册表(所有发布信息)
     * @param userId
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageInfo<Publish> queryAlbumList(Long userId, Integer page, Integer pageSize) {
        PageInfo<Publish> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal(0);  //不提供总数

        PageRequest pageRequest = PageRequest.of(page-1,pageSize,Sort.by(Sort.Order.desc("created")));
        Query query = new Query().with(pageRequest);

        //查找相册表
        List<Album> albumList = this.mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);

        if(CollectionUtils.isEmpty(albumList)){
            return pageInfo;
        }

        //获取所有相册表的id
        List<ObjectId> publishIds = new ArrayList<>();
        for (Album album : albumList) {
            publishIds.add(album.getPublishId());
        }

        //查询发布信息
        Query queryPublish = Query.query(Criteria.where("id").in(publishIds)).with(Sort.by(Sort.Order.desc("created")));

        List<Publish> publishList = this.mongoTemplate.find(queryPublish, Publish.class);

        pageInfo.setRecords(publishList);

        return pageInfo;

    }
}

